Latest update: June 2015
This tutorial demonstrates how to start the FlashAir's wireless LAN in AP mode using iSDIO.
To start in AP mode, use the 'Establish' command regulated by iSDIO.
After the Establish command is issued, it can take about 20 seconds for the FlashAir to start up in AP mode.
To make sure the FlashAir is starting, use the status register.
We explained how to read the status register in Tutorial 3, but in this tutorial we aren't going to use the entire status register - we're only going to explain how to get the processing status after issuing a command.
Also, to run the Establish command properly, the FlashAir's wireless LAN should be unconnected. So, in this tutorial, we'll first run the Disconnect command to terminate any active wireless connections.
We're going to be adding to and modifying the source code from Tutorial 3.
As previously described, it takes time to complete processing after a command is issued. We use a sequential ID to determine which command is the latest.
iSDIO's sequential ID is an unsigned 32bit integer. Every time a new command issued, increment the sequential ID by 1.
If the FlashAir itself changes wireless LAN settings (for example, due to a CGI command), please note that an iSDIO command may be issues and the sequential ID changed.
Because of this, you might want to create your own self-managed ID, and update it by getting the latest sequential ID after each command is issued. In this tutorial, to keep things simplified, we'll be reading the sequential ID shortly after starting and using a self-managed ID after that.
uint32_t nextSequenceId = 0;
The Establish command will start up the FlashAir's wireless LAN in AP mode. In the background, the FlashAir will also start up HTTP and DHCP servers.
For more information, please read SD Specifications Part E7 Wireless LAN Simplified Addendum Version 1.10 4.2.3 Estalibsh(ssid, networkKey, encMode)
To assemble the command data, the following information is required:
3
)3
)boolean iSDIO_establish(uint32_t sequenceId) {
Serial.print(F("\nEstablish command: \n"));
memset(buffer, 0, 512);
uint8_t* p = buffer;
p = put_command_header(p, 1, 0);
p = put_command_info_header(p, 0x03, sequenceId, 3);
p = put_str_arg(p, "sdiotest");
p = put_str_arg(p, "12345678");
p = put_u8_arg(p, 0x06);
put_command_header(buffer, 1, (p - buffer));
printHex(buffer, (p - buffer));
return card.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
}
0x03
, sequential ID
sequenceID
, and the number of parameters
3
.0x06
for WPA2-PSK and AES. Please see the specification for other values. We also use a
helper function
to write our data.printHex()
function.To check the command processing status, we can read the command response status from iSDIO.
The most important parts are iSDIO command sequence id and Response Status. Make sure the iSDIO command sequence id is same as the sequence ID we want to check. After making sure the IDs are identical, check the processing status with the Response Status.
In addition, the iSDIO standard allows for up to eight commands to be issued at a time - however
FlashAir supports
only one, so we only need to read address
0x440
.
Make a function that waits for our command to end.
boolean iSDIO_waitResponse(uint32_t sequenceId) {
Serial.print(F("\nWaiting response "));
uint8_t prev = 0xFF;
for (int i = 0; i < 20; ++i) {
memset(buffer, 0, 0x14);
// Read command response status.
if (!card.readExtMemory(1, 1, 0x440, 0x14, buffer)) {
return false;
}
uint8_t resp = get_u8(buffer + 8);
if (sequenceId == get_u32(buffer + 4)) {
if (prev != resp) {
switch (resp) {
case 0x00:
Serial.print(F("\n Initial"));
break;
case 0x01:
Serial.print(F("\n Command Processing"));
break;
case 0x02:
Serial.println(F("\n Command Rejected"));
return false;
case 0x03:
Serial.println(F("\n Process Succeeded"));
return true;
case 0x04:
Serial.println(F("\n Process Terminated"));
return false;
default:
Serial.print(F("\n Process Failed "));
Serial.println(resp, HEX);
return false;
}
prev = resp;
}
}
Serial.print(F("."));
delay(1000);
}
return false;
}
The Disconnect command terminates the wireless LAN. It will also stop the HTTP and DHCP servers.
For more information, please read SD Specifications Part E7 Wireless LAN Simplified Addendum Version 1.10 4.2.7 Disconnect(ssid, networkKey, encMode)
To assemble the command data, the following information is required:
7
)0
)boolean iSDIO_disconnect(uint32_t sequenceId) {
Serial.print(F("\nDisconnect command: \n"));
memset(buffer, 0, 512);
uint8_t* p = buffer;
p = put_command_header(p, 1, 0);
p = put_command_info_header(p, 0x07, sequenceId, 0);
put_command_header(buffer, 1, (p - buffer));
printHex(buffer, (p - buffer));
return card.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
}
The main program is going to be interactive.
Depending on the number input from the Arduino's serial terminal, we'll either run "Status display", "Disconnect", or "Establish".
void loop() {
if (!iSDIO_status()) {
Serial.println(F("\nFailed to read status."));
}
Serial.print(F("\n0. Show status"));
Serial.print(F("\n1. Disconnect"));
Serial.print(F("\n2. Establish"));
Serial.print(F("\n\nCommand? (next sequence id = "));
Serial.print(nextSequenceId, DEC);
Serial.println(F(")"));
while (Serial.available() == 0);
char command = Serial.read();
switch (command - '0') {
case 0 :
break;
case 1 :
if (iSDIO_disconnect(nextSequenceId) &&
iSDIO_waitResponse(nextSequenceId)) {
Serial.println(F("\nSuccess."));
} else {
Serial.print(F("\nFailed or waiting. errorCode="));
Serial.println(card.errorCode(), HEX);
}
nextSequenceId++;
break;
case 2 :
if (iSDIO_establish(nextSequenceId) &&
iSDIO_waitResponse(nextSequenceId)) {
Serial.println(F("\nSuccess."));
} else {
Serial.print(F("\nFailed or waiting. errorCode="));
Serial.println(card.errorCode(), HEX);
}
nextSequenceId++;
break;
default :
Serial.println(F("\nUnknown command."));
break;
}
}
Since the status display was included in the
loop()
function, delete it from the
setup()
function.
void setup() {
// Initialize UART for message print.
Serial.begin(9600);
while (!Serial) {
;
}
// Initialize SD card.
Serial.print(F("\nInitializing SD card..."));
if (card.init(SPI_HALF_SPEED, chipSelectPin)) {
Serial.print(F("OK"));
} else {
Serial.print(F("NG"));
abort();
}
// Read the previous sequence ID.
if (card.readExtMemory(1, 1, 0x420, 0x34, buffer)) {
if (buffer[0x20] == 0x01) {
nextSequenceId = get_u32(buffer + 0x24);
iSDIO_waitResponse(nextSequenceId);
nextSequenceId++;
} else {
nextSequenceId = 0;
}
} else {
Serial.println(F("\nFailed to read status."));
nextSequenceId = 0;
}
}
Initializing SD card...OK
Wait for response
Process Succeeded
Read iSDIO Status Register
== iSDIO Status Registers ==
[0400h] Command Write Status:
... (snip) ...
[0440h] Command Response Status #1: id = 3, sequence id = 1, status = Process Succeeded
... (snip) ...
[0506h] WLAN: No Scan, No WPS, Group Client, AP, Infrastructure, No Connection,
... (snip) ...
[0550h] IP Address: 192.168.0.1
... (snip) ...
0. Show status
1. Disconnect
2. Establish
Command? (next sequence id = 2)
The current status is displayed at the start, in this example the FlashAir started in AP mode.
Input your command in the box at the top of serial terminal in the Arduino IDE.
1
Input Enter.
Disconnect command:
00: 01010000180000000000000000000700
01: 0700000000000000
Wait for response
Command Processing.
Process Succeeded
Success.
Read iSDIO Status Register
... (snip) ...
[0440h] Command Response Status #1: id = 7, sequence id = 2, status = Process Succeeded
... (snip) ...
[0506h] WLAN: No Scan, No WPS, Group Client, STA, Initial, No Connection,
... (snip) ...
[0550h] IP Address: 0.0.0.0
... (snip) ...
Command? (next sequence id = 3)
Line 14 indicates that a disconnect command was issued and completed (Disconnect command
ID is
7
), shows the assigned sequential ID, and status (
Process Succeeded
). You can tell that the wireless LAN is disconnected because it's set to
STA mode,
and the IP Address is
0.0.0.0
.
Lines 3 to 4 are command data. Check them if something goes wrong.
Next, lets start AP mode.
Input
2
, in the serial terminal box.
Establish command:
00: 01010000380000000000000000000300
01: 0800000003000000080000007364696F
02: 74657374080000003132333435363738
03: 0100000006000000
Wait for response
Command Processing.....
Process Succeeded
Success.
Read iSDIO Status Register
... (snip) ...
[0440h] Command Response Status #1: id = 3, sequence id = 3, status = Process Succeeded
... (snip) ...
[0506h] WLAN: No Scan, No WPS, Group Client, AP, Infrastructure, No Connection,
[0508h] SSID: sdiotest
[0528h] Encryption Mode: WPA2-PSK and AES
[0529h] Signal Strength: 0
[052Ah] Channel: 11
[0530h] MAC Address: E8E0B758A7FB
[0540h] ID:
[0550h] IP Address: 192.168.0.1
[0554h] Subnet Mask: 255.255.255.0
[0558h] Default Gateway: 192.168.0.1
[055Ch] Preferred DNS Server: 192.168.0.1
[0560h] Alternate DNS Server: 0.0.0.0
... (snip) ...
An Establish command (ID
3
) has been executed. (
Line 16)
You can see that the FlashAir started in AP mode because the WLAN status is
AP
and the IP Address is
192.168.0.1
.
arduino_tutorial_04.zip (24KB)
All sample code on this page is licensed under BSD 2-Clause License.